package com.gooview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.OvershootInterpolator;

import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;

public class GooView extends View {
    private Paint paint;

    public GooView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public GooView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GooView(Context context) {
        super(context);
        init();
    }

    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置抗锯齿
        paint.setColor(Color.RED);
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                int cx = (getWidth() + getPaddingLeft() - getPaddingRight()) / 2;
                int cy = (getHeight() + getPaddingTop() + -getPaddingBottom()) / 2;
                dragCenter .set(cx + 150, cy);//拖拽圆的圆心
                stickyCenter.set(cx, cy);//固定圆的圆心
            }
        });
    }


    private PointF dragCenter= new PointF();//拖拽圆的圆心
    private PointF stickyCenter = new PointF();//固定圆的圆心
    private float dragRadius = 20f;//拖拽圆的半径
    private float stickyRadius = 20f;//固定圆的半径

    //	// TODO: 2017/12/29 用于绘制贝塞尔曲线的四个点
//    private PointF[] stickyPoints = {new PointF(500f, 220f), new PointF(500f, 260f)};
//    private PointF[] dragPoints = {new PointF(200f, 220f), new PointF(200f, 260f)};
//    private PointF controlPoint = new PointF(350f, 240f);

    private double lineK;//todo 斜率


     private float maxDistance = 300;
    private boolean isDragOutOfRange = false;


//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
//        int cx = (getMeasuredWidth() + getPaddingLeft() - getPaddingRight()) / 2;
//        int cy = (getMeasuredHeight() + getPaddingTop() + -getPaddingBottom()) / 2;
//        dragCenter .set(cx + 150, cy);//拖拽圆的圆心
//        stickyCenter.set(cx, cy);//固定圆的圆心
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //todo 让整体画布向上偏移一个状态栏高度
        canvas.translate(0, -Utils.getStatusBarHeight(getResources()));


        //todo dragPoint: 2圆圆心连线的垂线与drag圆的交点
        //stickyPoint: 2圆圆心连线的垂线与sticky圆的交点
        //todo 根据dragCenter动态求出dragPoint和stickyPoint
        float xOffset = dragCenter.x - stickyCenter.x;
        float yOffset = dragCenter.y - stickyCenter.y;
        if (xOffset != 0) {
            //fixme drag不在固定圆的正上方
            lineK = yOffset / xOffset;  //todo 通过斜率可知角度
        }
        //todo 动态获取固定圆的半径
        stickyRadius = getStickyRadius();
        //todo 通过指定圆心，斜率lineK 获取直线与圆的交点

        //动态计算控制点
        PointF[]  dragPoints = GeometryUtil.getIntersectionPoints(dragCenter, dragRadius, lineK);
        PointF[] stickyPoints = GeometryUtil.getIntersectionPoints(stickyCenter, stickyRadius, lineK);
        PointF controlPoint = GeometryUtil.getPointByPercent(dragCenter, stickyCenter, 0.618f);


        //todo 绘制两个圆
        canvas.drawCircle(dragCenter.x, dragCenter.y, dragRadius, paint);
        //fixme 超出范围不让小圆变小就把绘制的代码放到判断条件中
        canvas.drawCircle(stickyCenter.x, stickyCenter.y, stickyRadius, paint);
        // todo  绘制贝塞尔曲线,条件是不超出拖拽范围
        if (!isDragOutOfRange) {
            Path path = new Path();
            path.moveTo(stickyPoints[0].x, stickyPoints[0].y);
            path.quadTo(controlPoint.x, controlPoint.y, dragPoints[0].x, dragPoints[0].y);
            path.lineTo(dragPoints[1].x, dragPoints[1].y); //fixme  注意不是moveTo,要连线
            path.quadTo(controlPoint.x, controlPoint.y, stickyPoints[1].x, stickyPoints[1].y);
            canvas.drawPath(path, paint);
        }

        //todo 绘制边界圆，以固定圆圆心为圆心，然后80为半径
        paint.setStyle(Paint.Style.STROKE);//设置只有边线
        canvas.drawCircle(stickyCenter.x, stickyCenter.y, maxDistance, paint);
        paint.setStyle(Paint.Style.FILL);
    }

    /**
     * todo 固定圆半径变化 动态求出固定圆半径
     */
    private float getStickyRadius() {
        float radius;
        //求出2个圆心之间的距离
        float centerDistance = GeometryUtil.getDistanceBetween2Points(dragCenter, stickyCenter);
        float fraction = centerDistance/maxDistance;//圆心距离占总距离的百分比
        radius = GeometryUtil.evaluateValue(fraction, 12f, 4f);
        return radius;
    }
    final ValueAnimator  valueAnimator = ObjectAnimator.ofFloat(1);
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getRawX();  //todo  因为这个控件可以拖拽到父容器以外,所以用getRawX()更合适
        float y = event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                valueAnimator.cancel();
               isDragOutOfRange = false; //todo 控制超范围绘制
//                dragCenter.set(x, y);
//                break;
            case MotionEvent.ACTION_MOVE:
                dragCenter.set(x, y);
                // FIXME: 超出范围，应该断掉，不再绘制贝塞尔曲线的部分
                if (GeometryUtil.getDistanceBetween2Points(dragCenter, stickyCenter) > maxDistance) {
                    isDragOutOfRange = true;
                } else {
                    isDragOutOfRange = false; //todo 控制超范围绘制
                }
                break;
            case MotionEvent.ACTION_UP:
                // todo 超出范围动画弹回去
                if(GeometryUtil.getDistanceBetween2Points(dragCenter, stickyCenter)>maxDistance){
                    dragCenter.set(stickyCenter.x, stickyCenter.y);
                }else {
                    if(isDragOutOfRange){
                        //如果曾经超出范围过
                        dragCenter.set(stickyCenter.x, stickyCenter.y);
                    }else {
                        //动画的形式回去


                        //todo 起点
                        final PointF startPointF = new PointF(dragCenter.x, dragCenter.y);
                        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                            @Override
                            public void onAnimationUpdate(ValueAnimator animator) {
                                //todo 动画执行的百分比
                                float animatedFraction = animator.getAnimatedFraction();
                                Log.e("tag", "animatedFraction: "+animatedFraction);
                                PointF pointF = GeometryUtil.getPointByPercent(startPointF, stickyCenter, animatedFraction);
                                dragCenter.set(pointF);
                                invalidate(); //fixme 注意刷新重绘
                            }
                        });
                        valueAnimator.setDuration(500);
                        valueAnimator.setInterpolator(new OvershootInterpolator(3));
                        valueAnimator.start();
                    }
                }
                break;
        }
        invalidate(); //todo 重绘
        return true;  // FIXME: 2017/12/29 注意
    }

}
